package com.cman777.springc.web.config;

import com.cman777.springc.common.helper.EnvUtil;
import com.cman777.springc.common.helper.JsonHelper;
import com.cman777.springc.web.config.formatter.*;
import com.cman777.springc.web.filter.MdcFilter;
import com.cman777.springc.web.util.RestTemplateUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;

/**
 * @author chenzhicong
 * @time 2019/11/9 17:01
 * @description
 */
@Configuration
@Log4j2
@ComponentScan("com.cman777.springc.web")
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 貌似不手动配置jackson消息转换器没有使用objectMapper，奇怪。
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            if (MappingJackson2HttpMessageConverter.class == converter.getClass()) {
                ((MappingJackson2HttpMessageConverter) converter).setObjectMapper(JsonHelper.getMvcObjectMapper());
            }
        }
    }


    /**
     * dev和test环境允许跨域
     * 这个过滤器一定要排在第一
     *
     * @return
     */
    @Conditional(value = {EnvUtil.DevOrTestCondition.class})
    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource =
                new UrlBasedCorsConfigurationSource();

        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);

        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setOrder(10);
        filterRegistrationBean.setFilter(new CorsFilter(urlBasedCorsConfigurationSource));
        filterRegistrationBean.setName("corsFilter");
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }

    /**
     * 添加一个mdc码
     */
    @Bean
    public FilterRegistrationBean mdcFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new MdcFilter());
        filterRegistrationBean.setOrder(20);
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setName("mdcFilter");
        return filterRegistrationBean;
    }

    /**
     * 配置资源映射，如果是默认设置不会读取到swagger-ui.html
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations(
                "classpath:/static/");
        registry.addResourceHandler("swagger-ui.html").addResourceLocations(
                "classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(LocalDateTimeFormatter.INSTANCE);
        registry.addFormatter(LocalDateFormatter.INSTANCE);
        registry.addFormatter(LocalTimeFormatter.INSTANCE);
        registry.addFormatter(YearFormatter.INSTANCE);
        registry.addFormatter(MonthDayFormatter.INSTANCE);
        registry.addFormatter(YearMonthFormatter.INSTANCE);
    }

    @Bean
    public RestTemplate myRestTemplate() {
       return RestTemplateUtil.getRestTemplate();
    }

}
